#include "Timer.h"
#include "AutoLock.h"


typedef std::map<UINT, boost::tuple<Timer*, TimerCallback> >   TimerStore;
TimerStore* gTimerCallbacks = 0;

void CALLBACK Timer::MyTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime){
	if(gTimerCallbacks){
		TimerStore::iterator it = gTimerCallbacks->find(idEvent);
		if(it != gTimerCallbacks->end()){
			boost::tuple<Timer*, TimerCallback>& tup = it->second;
			Timer* timer = tup.get<0>();
			if( !  (tup.get<1>() )(idEvent, timer->elapse_) ){
				timer->Stop();
			}
		}
	}else{
		KillTimer(0, idEvent);
	}
}


Timer::Timer(){
	ThreadLock lock("Timer::Timer");
	elapse_ = 0;
	if(!gTimerCallbacks){
		gTimerCallbacks = new TimerStore();
	}
}
Timer::~Timer(){
	ThreadLock lock("Timer::~Timer");
	assert(gTimerCallbacks);
	if(timerID){
#ifdef _DEBUG
		OutputDebugString(_T("警告: Timer对象释放时定时器没有被用Stop方法!!\n"));
#endif
		KillTimer(0, timerID);
		gTimerCallbacks->erase(timerID);
		timerID = 0;
	}
	if(gTimerCallbacks->size()==1){
		gTimerCallbacks->clear();
		delete gTimerCallbacks;
		gTimerCallbacks = 0;
	}
}
UINT Timer::ReStart(){
	assert(elapse_);
	return Start(elapse_, callback_);
}
UINT Timer::Start(UINT elapse, TimerCallback callback){
	assert(elapse);
	elapse_ = elapse;
	callback_ = callback;
	Stop();
	timerID = SetTimer(0, 0, elapse_, &MyTimerProc);
	(*gTimerCallbacks)[timerID] = boost::make_tuple(this, callback_);
	return timerID;
}
void Timer::Stop(){
	if(timerID){
		gTimerCallbacks->erase(timerID);
		KillTimer(0, timerID);
		timerID = 0;
	}
}
bool Timer::IsActive(){
	return timerID != 0;
}
UINT Timer::GetTimerID(){
	return timerID;
}
